﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using SLE = System.Linq.Enumerable;


namespace NotifiableLinqTests.FrameWork
{
	public class Source<T> : ObservableCollection<T>
	{
		protected static readonly Random _rnd = new Random();

		public NotificationTestsBase<T> NotificationTestsBase { get; set; }
		/// <summary>
		/// switch to random case, balanced by weight
		/// </summary>
		static Dictionary<Action, int> BalancedSwitch
		{
			set
			{
				var sum = SLE.Sum(value.Values);
				var rnd = _rnd.Next(sum);
				var c = 0;
				foreach (var kvp in value)
				{
					c += kvp.Value;
					if (c >= rnd)
					{
						kvp.Key();
						break;
					}
				}
			}
		}

		public int Times = 200;
		public string Name = "Source";
		public void LetsDance(Action verify)
		{
			verify();
			for (var i = 0; i < Times; i++)
			{
				BalancedSwitch = new Dictionary<Action, int> { { () =>
				{
					var newItem = NotificationTestsBase.CreateNewItem();
					// Trace.WriteLine("# ADD " + newItem);
					Add(newItem);
				}, 10 }, { () =>
				{
					if (Count > 0)
					{
						var index = _rnd.Next(Count);
						// Trace.WriteLine("# REM " + index);
						RemoveAt(index);
					}
				}, 10 }, { () =>
				{
					if (Count > 0)
					{
						var index = _rnd.Next(Count);
						// Trace.WriteLine("# CHG " + index);
						NotificationTestsBase.ModifyItem(this[index]);
					}
				}, 25 }, };

				// Trace.WriteLine("# " + Name + ": " + string.Join(", ", this.Select(x => x.ToString()).ToArray()));
				verify();
			}
		}
	}
}
